package com.lgy.ms.service.aop;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.lgy.ms.core.bean.RequestParams;
import com.lgy.ms.core.bean.ResponseParams;
import com.lgy.ms.core.bean.SessionInfo;
import com.lgy.ms.core.exception.AppException;
import com.lgy.ms.service.service.base.AppBaseService;
import com.lgy.ms.service.service.base.AppRequestParam;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * @author Gylin
 */
@Aspect
@Component
public class AppServiceAop {

    private Logger log = LoggerFactory.getLogger(AppServiceAop.class);

    @Pointcut("execution(public * com.lgy.ms.service.service.business.*.*(..))")
    public void doService() {
    }

    @Before("doService()")
    public void doBeforeCallService(JoinPoint jp) throws AppException {
        Object obj = jp.getTarget();
        String method = jp.getSignature().getName();
        Object[] objParam = jp.getArgs();
        if (obj instanceof AppBaseService) {
            AppBaseService appBaseService = (AppBaseService) obj;
            if (objParam.length > 0) {
                if (objParam[0] instanceof RequestParams) {
                    RequestParams requestParams = (RequestParams) objParam[0];
                    log.info(">>> req[{}]-obj[{}]-method[{}]-requestMsg[{}]", requestParams.getReqNo(), obj, method, JSON.toJSONString(requestParams, SerializerFeature.DisableCircularReferenceDetect));
                    AppRequestParam.set(requestParams);
                    appBaseService.setSessionInfoToLocalThreadParam();
                }
            }
        }
    }

    @AfterReturning(returning = "ret", pointcut = "doService()")
    private void doAfterCallService(JoinPoint jp, Object ret) {
        Object obj = jp.getTarget();
        if (obj instanceof AppBaseService) {
            AppBaseService appBaseService = (AppBaseService) obj;
            SessionInfo sessionInfo = AppRequestParam.getSessionInfo();
            if (sessionInfo != null) {
                if (((System.currentTimeMillis() - sessionInfo.getLastSaveTime()) / (1000 * 60)) > 10) {
                    appBaseService.saveSessionInfo(sessionInfo);
                }
            }
        }

        ResponseParams<?> resp = null;
        if (ret instanceof ResponseParams<?>) {
            resp = (ResponseParams<?>) ret;
        }
        String method = jp.getSignature().getName();
        Object[] objParam = jp.getArgs();
        if (objParam.length > 0) {
            if (objParam[0] instanceof RequestParams) {
                RequestParams requestParams = (RequestParams) objParam[0];
                log.info("<<< resp[{}]-obj[{}]-method[{}]-responseMsg[{}]", requestParams.getReqNo(), obj, method, JSON.toJSONString(resp, SerializerFeature.DisableCircularReferenceDetect));
            }
        }
        AppRequestParam.remove();
    }
}
